package com.demo.common;

import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.util.Assert;

/**
 * Aop代理工具
 * 继承SpringAop代理工具类
 * 增加方法 ：ultimateTargetObject (用来取得原始代理对象的方法)
 * @author ryuu.kk
 *
 */
public abstract class AopProxyUtils extends org.springframework.aop.framework.AopProxyUtils {

	
	/**
	 * 取得原始代理对象,
	 * 如果该对象由多个代理形成一种代理链,则一直遍历到原始对象为止
	 * @param candidate 代理对象
	 * @return Object 原始对象
	 * @see org.springframework.aop.TargetClassAware#getTargetClass()
	 * @see org.springframework.aop.framework.Advised#getTargetSource()
	 */
	public static Object ultimateTargetObject(Object candidate) {
		Assert.notNull(candidate, "Candidate object must not be null");
		Object current = candidate;
		//Class<?> result = null;
		while (current instanceof TargetClassAware) {
			//result = ((TargetClassAware) current).getTargetClass();
			Object nested = null;
			if (current instanceof Advised) {
				TargetSource targetSource = ((Advised) current).getTargetSource();
				if (targetSource instanceof SingletonTargetSource) {
					nested = ((SingletonTargetSource) targetSource).getTarget();
				}
			}
			current = nested;
		}
//		if (result == null) {
//			result = (AopUtils.isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
//		}
		return current;
	}
}
